import {
    _decorator,
    Component,
    instantiate,
    LabelComponent,
    LayoutComponent,
    Node,
    NodeEventType,
    Prefab,
    Size,
    sys,
    UITransformComponent,
    v3,
    Vec3,
    Event,
    Vec2,
    EventTouch,
    tween,
    Tween,
    director, AudioClip,
    SpriteComponent, Sprite, assetManager, ImageAsset, SpriteFrame, Texture2D,
    Color
} from 'cc';
import {MathUtil} from "db://assets/scripts/MathUtil";
import {Item} from "db://assets/scripts/Item";
import {WxUser} from "db://assets/scripts/dto/WxUser";
import {get, post} from "db://assets/scripts/config/Api";
import {GameUser} from "db://assets/scripts/dto/GameUser";
import {Vec3DTO} from "db://assets/scripts/dto/Vec3DTO";
import {Modal} from "db://assets/scripts/component/Modal";
import {AudioMgr} from "db://assets/scripts/component/AudioMgr";
import {WebsocketMgr} from "db://assets/scripts/component/WebsocketMgr";
import {RoofInfoDTO} from "db://assets/scripts/dto/RoofInfoDTO";
import {Grid} from "db://assets/scripts/util/grid";
import {AI} from "db://assets/scripts/util/ai";
import {Tile} from "db://assets/scripts/util/tile";
import {Palette} from "db://assets/scripts/component/Palette";


const {ccclass, property} = _decorator;

class ItemPosition {
    position: Vec3;
    item: Node;

    constructor(position: Vec3, item?: Node) {
        this.position = position;
        this.item = item;
    }
}

@ccclass('Game')
export class Game extends Component {


    @property(Node)
    gameMain: Node = null!;

    @property(Node)
    overGame: Node = null!;

    userData: GameUser = null;

    @property(LabelComponent)
    lvLabel: LabelComponent = null!;

    @property(LabelComponent)
    scoreLabel: LabelComponent = null!;

    @property(LabelComponent)
    topScoreLabel: LabelComponent = null!;

    @property(LabelComponent)
    backLabel: LabelComponent = null!;

    @property(Node)
    ndParend: Node = null!;

    @property(Node)
    squereParent: Node = null!;

    @property(Prefab)
    itemBgPrefab: Prefab = null!;

    @property(Prefab)
    itemPrefab: Prefab = null!;

    ndLayoutComponent: LayoutComponent = null!;

    squareArray: [ItemPosition[]] = null;


    squureWh: number = null;

    @property(Node)
    canvas: Node = null!;

    @property(LabelComponent)
    finalScoreTextLabel: LabelComponent = null!;

    touchStartPosition: Vec2 = null;
    touchEndPosition: Vec2 = null;

    isGame: boolean = false;

    userInfo: WxUser;
    currentScore: number = 0;

    @property(AudioClip)
    bgMusic: AudioClip = null!;

    @property(AudioClip)
    sliderMusic: AudioClip = null;

    @property(AudioClip)
    mergeMusic: AudioClip = null;

    @property(Prefab)
    rankPrefab: Prefab = null!;

    @property(Node)
    rankParent: Node = null!;


    start() {
        this.initPanel();
        this.ndLayoutComponent = this.ndParend.getComponent(LayoutComponent);
        this.addTouch();
        this.userInfo = JSON.parse(localStorage.getItem('userInfo'));
        this.startGame();
        this.showRank();

    }

    update(deltaTime: number) {

    }

    private addTouch() {
        this.canvas.on(NodeEventType.TOUCH_START, this.touchStart, this);
        this.canvas.on(NodeEventType.TOUCH_MOVE, this.touchMove, this);
        this.canvas.on(NodeEventType.TOUCH_CANCEL, this.touchCancel, this);
        this.canvas.on(NodeEventType.TOUCH_END, this.touchEnd, this);
    }

    private touchStart(event: EventTouch) {
        if (!this.isGame) return;
        this.touchStartPosition = event.getLocation();
    }

    private touchMove(event: EventTouch) {

    }

    private touchCancel(event: EventTouch) {

    }

    private touchEnd(event: EventTouch) {
        if (!this.isGame) return;
        this.touchEndPosition = event.getLocation();
        console.log("起点:" + this.touchStartPosition + "-结束:" + this.touchEndPosition);
        let offsetX = this.touchEndPosition.x - this.touchStartPosition.x;
        let offsetY = this.touchEndPosition.y - this.touchStartPosition.y;
        if (Math.abs(offsetX) < 5
            && Math.abs(offsetY) < 5) {
            return;
        }

        // x轴滑动
        if (Math.abs(offsetX) > Math.abs(offsetY)) {
            if (offsetX > 0) {
                // 右移
                this.moveSquare("right")
            } else {
                // 左移
                this.moveSquare("left")
            }
        } else {
            // y轴滑动
            if (offsetY > 0) {
                // 上划
                this.moveSquare("up")
            } else {
                // 下划
                this.moveSquare("down")
            }
        }
    }

    public moveSquare(type: string) {
        this.currentScore = 0;
        // this.squareArrayHistory.push(this.copyArray());
        // 记录当前记录
        let isMove: boolean = false;
        switch (type) {
            case "left":
                console.log("左移");
                isMove = this.moveLeft();
                break;
            case "right":
                console.log("右移");
                isMove = this.moveRight();
                break;
            case "up":
                console.log("上移");
                isMove = this.moveUp();
                break;
            case "down":
                console.log("下移");
                isMove = this.moveDown();
                break;
        }
        if (isMove) {
            AudioMgr.inst.playOneShot(this.sliderMusic);
            this.generateRandom();
            this.setScore(this.currentScore);
            this.currentScore = 0;
        }
        // 判断是否游戏结束
        // 获取所有等于0的位置

        let isGameOver: boolean = true;
        breakIsGameOVer:
            for (let i = 0; i < this.squareArray.length; i++) {
                // 每一列的长度
                const columnLength = this.squareArray[i].length;
                // 判断后面是否有空格
                for (let j = 0; j < columnLength; j++) {
                    if (this.squareArray[i][j]?.position.z === 0) {
                        isGameOver = false;
                        break breakIsGameOVer;
                    }
                    if (this.squareArray[i][j]?.position.z
                        === this.squareArray?.[i + 1]?.[j]?.position?.z) {
                        isGameOver = false;
                        break breakIsGameOVer;
                    }
                    if (this.squareArray[i][j]?.position.z
                        === this.squareArray?.[i - 1]?.[j]?.position?.z) {
                        isGameOver = false;
                        break breakIsGameOVer;
                    }
                    if (this.squareArray[i][j]?.position.z
                        === this.squareArray?.[i]?.[j + 1]?.position?.z) {
                        isGameOver = false;
                        break breakIsGameOVer;
                    }
                    if (this.squareArray[i][j]?.position.z
                        === this.squareArray?.[i]?.[j - 1]?.position?.z) {
                        isGameOver = false;
                        break breakIsGameOVer;
                    }
                }
            }
        if (isGameOver) {
            this.overGame.active = true;
            this.finalScoreTextLabel.string = "你得到了" + this.userData.score + "分";
            this.gameOver()
            this.showRank()
        }
    }

    private async gameOver() {
        this.userData.gameOver = 1;
        this.isGame = false;
        await post("/game/updateGameUser/" + this.userData.id, this.userData);
    }

    private clickCloseGameOver() {
        this.overGame.active = false;
    }

    private printArray() {
        for (const squareArrayElement of this.squareArray) {
            for (const itemPosition of squareArrayElement) {
                console.log(`x:${itemPosition.position.x},y:${itemPosition.position.y},z:${itemPosition.position.z}, item:${itemPosition.item}`)
            }
        }
    }


    /**
     * 撤回
     * @private
     */
    private async cancel() {

        // 清除
        if (this.userData.backNum > 0
            && this.squereParent.children.length > 2) {

            if (this.squereParent.children.length > 0) {
                this.squereParent.destroyAllChildren();
                this.squareArray = null;
            }

            this.userData.backNum--;
            this.userData.arrayHistory.pop();
            this.userData.array = this.userData.arrayHistory.pop();
            this.userData.arrayHistory.push(this.userData.array);
            this.initSqure();

            for (const squareArrayElement of this.squareArray) {
                for (const itemPosition of squareArrayElement) {
                    if (itemPosition.position.z !== 0) {
                        this.addItem(itemPosition, false);
                    }
                }
            }

            this.userData = await post<GameUser>("/game/updateGameUser/" + this.userData.id, this.userData);

            this.updateView();
        }
    }

    private moveUp(): boolean {
        // 左移,交换每个空格,然后看看能不能合成
        // 循环每一行
        let isMove: boolean = false;


        for (let i = 0; i < this.squareArray.length; i++) {
            // 每一列的长度
            const columnLength = this.squareArray[i].length;

            // 判断后面是否有空格
            for (let j = 0; j < columnLength; j++) {
                // 有空格，往前移动
                if (this.squareArray[j][i].position?.z === 0) {
                    for (let k = j + 1; k < columnLength; k++) {
                        if (this.squareArray[k][i].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[j][i].position.z = this.squareArray[k][i].position.z;
                            this.squareArray[j][i].item = this.squareArray[k][i].item;
                            this.squareArray[k][i].position.z = 0;
                            this.squareArray[k][i].item = null;
                            this.moveAnimation(tween(this.squareArray[j][i].item), this.squareArray[j][i].position);
                            break;

                        }
                    }
                }
            }


            // 合并
            for (let j = 1; j < columnLength; j++) {
                let h = j - 1;
                if (this.squareArray[j][i].position.z != 0
                    && this.squareArray[j][i].position.z === this.squareArray[h][i].position.z) {
                    isMove = true;
                    // 前一个*2
                    let num = this.squareArray[h][i].position.z * 2;
                    this.squareArray[h][i].position.z = num;
                    // 当前归零
                    this.squareArray[j][i].position.z = 0;
                    this.currentScore += this.squareArray[h][i].position.z;
                    let temp = this.squareArray[j][i].item;
                    let tempH = this.squareArray[h][i].item;
                    this.squareArray[j][i].item = null;
                    this.moveAnimation(tween(temp), this.squareArray[h][i].position, () => {
                        tempH.getComponent(Item).init(num);
                        temp.destroy();
                    });

                    tween(this.squareArray[h][i].item)
                        .to(0.2, {scale: v3(1.3, 1.3, 1.3)}, {easing: "sineIn"})
                        .to(0.2, {scale: v3(1, 1, 1)}, {easing: "sineOut"})
                        .start()
                }
            }

            //合并后再次移动
            // 判断后面是否有空格
            for (let j = 0; j < columnLength; j++) {
                // 有空格，往前移动
                if (this.squareArray[j][i].position?.z === 0) {
                    for (let k = j + 1; k < columnLength; k++) {
                        if (this.squareArray[k][i].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[j][i].position.z = this.squareArray[k][i].position.z;
                            this.squareArray[j][i].item = this.squareArray[k][i].item;
                            this.squareArray[k][i].position.z = 0;
                            this.squareArray[k][i].item = null;
                            this.moveAnimation(tween(this.squareArray[j][i].item), this.squareArray[j][i].position);
                            break;

                        }
                    }
                }
            }

        }
        return isMove;
    }

    private moveDown(): boolean {
        // 左移,交换每个空格,然后看看能不能合成
        // 循环每一行
        let isMove: boolean = false;


        for (let i = 0; i < this.squareArray.length; i++) {
            // 每一列的长度
            const columnLength = this.squareArray[i].length;

            // 判断后面是否有空格
            for (let j = columnLength - 1; j >= 0; j--) {
                // 有空格，往前移动
                if (this.squareArray[j][i].position?.z === 0) {
                    for (let k = j - 1; k >= 0; k--) {
                        if (this.squareArray[k][i].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[j][i].position.z = this.squareArray[k][i].position.z;
                            this.squareArray[j][i].item = this.squareArray[k][i].item;
                            this.squareArray[k][i].position.z = 0;
                            this.squareArray[k][i].item = null;
                            this.moveAnimation(tween(this.squareArray[j][i].item), this.squareArray[j][i].position);
                            break;

                        }
                    }
                }
            }


            // 合并
            for (let j = columnLength - 2; j >= 0; j--) {
                let h = j + 1;
                if (this.squareArray[j][i].position.z != 0
                    && this.squareArray[j][i].position.z === this.squareArray[h][i].position.z) {
                    isMove = true;
                    // 前一个*2
                    let num = this.squareArray[h][i].position.z * 2;
                    this.squareArray[h][i].position.z = num;
                    // 当前归零
                    this.squareArray[j][i].position.z = 0;
                    this.currentScore += this.squareArray[h][i].position.z;
                    let temp = this.squareArray[j][i].item;
                    let tempH = this.squareArray[h][i].item;
                    this.squareArray[j][i].item = null;
                    this.moveAnimation(tween(temp), this.squareArray[h][i].position, () => {
                        tempH.getComponent(Item).init(num);
                        temp.destroy();
                    });

                    tween(this.squareArray[h][i].item)
                        .to(0.2, {scale: v3(1.3, 1.3, 1.3)}, {easing: "sineIn"})
                        .to(0.2, {scale: v3(1, 1, 1)}, {easing: "sineOut"})
                        .start()
                }
            }

            //合并后再次移动
            // 判断后面是否有空格
            for (let j = columnLength - 1; j >= 0; j--) {
                // 有空格，往前移动
                if (this.squareArray[j][i].position?.z === 0) {
                    for (let k = j - 1; k >= 0; k--) {
                        if (this.squareArray[k][i].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[j][i].position.z = this.squareArray[k][i].position.z;
                            this.squareArray[j][i].item = this.squareArray[k][i].item;
                            this.squareArray[k][i].position.z = 0;
                            this.squareArray[k][i].item = null;
                            this.moveAnimation(tween(this.squareArray[j][i].item), this.squareArray[j][i].position);
                            break;

                        }
                    }
                }
            }

        }
        return isMove;
    }

    private moveRight(): boolean {
        // 左移,交换每个空格,然后看看能不能合成
        // 循环每一行
        let isMove: boolean = false;


        for (let i = 0; i < this.squareArray.length; i++) {
            // 每一列的长度
            const columnLength = this.squareArray[i].length;

            // 判断后面是否有空格
            for (let j = columnLength - 1; j >= 0; j--) {
                // 有空格，往前移动
                if (this.squareArray[i][j].position?.z === 0) {
                    for (let k = j - 1; k >= 0; k--) {
                        if (this.squareArray[i][k].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[i][j].position.z = this.squareArray[i][k].position.z;
                            this.squareArray[i][j].item = this.squareArray[i][k].item;
                            this.squareArray[i][k].position.z = 0;
                            this.squareArray[i][k].item = null;
                            this.moveAnimation(tween(this.squareArray[i][j].item), this.squareArray[i][j].position);
                            break;

                        }
                    }
                }
            }


            // 合并
            for (let j = columnLength - 2; j >= 0; j--) {
                let h = j + 1;
                if (this.squareArray[i][j].position.z != 0
                    && this.squareArray[i][j].position.z === this.squareArray[i][h].position.z) {
                    isMove = true;
                    // 前一个*2
                    let num = this.squareArray[i][h].position.z * 2;
                    this.squareArray[i][h].position.z = num;
                    // 当前归零
                    this.squareArray[i][j].position.z = 0;
                    this.currentScore += this.squareArray[i][h].position.z;

                    let temp = this.squareArray[i][j].item;
                    let tempH = this.squareArray[i][h].item;
                    this.squareArray[i][j].item = null;
                    this.moveAnimation(tween(temp), this.squareArray[i][h].position, () => {
                        tempH.getComponent(Item).init(num);

                        temp.destroy();
                    });

                    tween(this.squareArray[i][h].item)
                        .to(0.2, {scale: v3(1.3, 1.3, 1.3)}, {easing: "sineIn"})
                        .to(0.2, {scale: v3(1, 1, 1)}, {easing: "sineOut"})
                        .start()
                }
            }

            //合并后再次移动
            // 判断后面是否有空格
            for (let j = columnLength - 1; j >= 0; j--) {
                // 有空格，往前移动
                if (this.squareArray[i][j].position?.z === 0) {
                    for (let k = j - 1; k >= 0; k--) {
                        if (this.squareArray[i][k].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[i][j].position.z = this.squareArray[i][k].position.z;
                            this.squareArray[i][j].item = this.squareArray[i][k].item;
                            this.squareArray[i][k].position.z = 0;
                            this.squareArray[i][k].item = null;
                            this.moveAnimation(tween(this.squareArray[i][j].item), this.squareArray[i][j].position);
                            break;

                        }
                    }
                }
            }

        }
        return isMove;
    }

    private moveLeft(): boolean {
        // 左移,交换每个空格,然后看看能不能合成
        // 循环每一行
        let isMove: boolean = false;


        for (let i = 0; i < this.squareArray.length; i++) {
            // 每一列的长度
            const columnLength = this.squareArray[i].length;

            // 判断后面是否有空格
            for (let j = 0; j < columnLength; j++) {
                // 有空格，往前移动
                debugger
                if (this.squareArray[i][j].position?.z === 0) {
                    for (let k = j + 1; k < columnLength; k++) {
                        if (this.squareArray[i][k].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[i][j].position.z = this.squareArray[i][k].position.z;
                            this.squareArray[i][j].item = this.squareArray[i][k].item;
                            this.squareArray[i][k].position.z = 0;
                            this.squareArray[i][k].item = null;
                            this.moveAnimation(tween(this.squareArray[i][j].item), this.squareArray[i][j].position);
                            break;

                        }
                    }
                }
            }


            // 合并
            for (let j = 1; j < columnLength; j++) {
                let h = j - 1;
                if (this.squareArray[i][j].position.z != 0
                    && this.squareArray[i][j].position.z === this.squareArray[i][h].position.z) {
                    isMove = true;
                    // 前一个*2
                    let num = this.squareArray[i][h].position.z * 2;
                    this.squareArray[i][h].position.z = num;
                    // 当前归零
                    this.squareArray[i][j].position.z = 0;
                    this.currentScore += this.squareArray[i][h].position.z;

                    let temp = this.squareArray[i][j].item;
                    let tempH = this.squareArray[i][h].item;
                    this.squareArray[i][j].item = null;


                    this.moveAnimation(tween(temp), this.squareArray[i][h].position, () => {
                        tempH.getComponent(Item).init(num);
                        temp.destroy();
                    });

                    tween(this.squareArray[i][h].item)
                        .to(0.2, {scale: v3(1.3, 1.3, 1.3)}, {easing: "sineIn"})
                        .to(0.2, {scale: v3(1, 1, 1)}, {easing: "sineOut"})
                        .start()
                }
            }

            //合并后再次移动
            // 判断后面是否有空格
            for (let j = 0; j < columnLength; j++) {
                // 有空格，往前移动
                if (this.squareArray[i][j].position?.z === 0) {
                    for (let k = j + 1; k < columnLength; k++) {
                        if (this.squareArray[i][k].position.z !== 0) {
                            // 不是0，往前移 交换位置
                            isMove = true;
                            console.log(`交换位置：${i}-${j} 和 ${i}-${k}`)
                            this.squareArray[i][j].position.z = this.squareArray[i][k].position.z;
                            this.squareArray[i][j].item = this.squareArray[i][k].item;
                            this.squareArray[i][k].position.z = 0;
                            this.squareArray[i][k].item = null;
                            this.moveAnimation(tween(this.squareArray[i][j].item), this.squareArray[i][j].position);
                            break;

                        }
                    }
                }
            }

        }
        return isMove;
    }


    private async init() {
        // 清除
        if (this.squereParent.children.length > 0) {
            this.squereParent.destroyAllChildren();
            this.squareArray = null;
        }
        await this.getUserInfo();
        this.updateView();
        this.initSqureBg();
        this.initSqure();

        for (const squareArrayElement of this.squareArray) {
            for (const itemPosition of squareArrayElement) {
                if (itemPosition.position.z !== 0) {
                    this.addItem(itemPosition, false);
                }
            }
        }
        this.testAi();

        this.isGame = true;
    }


    private initPanel() {
        this.gameMain.active = false;
        this.overGame.active = false;
    }


    private startGame() {
        this.gameMain.active = true;
        this.init();
        //  AudioMgr.inst.play(this.bgMusic, true);
    }


    private async reset() {
        this.overGame.active = false;
        this.gameMain.active = true;
        await this.gameOver()
        this.userData.backNum = 3;
        this.init();
    }


    private toLogin() {
        this.initPanel();
    }


    private async getUserInfo() {
        // 从服务器加载
        this.userData = await get<GameUser>("/game/getLastGameUser/2048")
        // 游戏已经结束
        if (this.userData == null
            || this.userData.gameOver === 1) {
            this.userData = await post<GameUser>("/game/startGameUser/2048");
        }

    }


    private updateView() {
        this.lvLabel.string = this.userData.lv + "x" + this.userData.lv;
        this.scoreLabel.string = this.userData.score + "";
        this.topScoreLabel.string = this.userInfo.game2048MaxScore + "";
        this.backLabel.string = "撤回 (" + this.userData.backNum + ")";
    }

    /**
     * 初始化方块
     * @private
     */


    private initSqureBg() {
        // 如果已经有个bg 就不生成了
        if (this.ndParend.children.length > 0) {
            return;
        }
        let lv: number = parseInt(this.userData.lv);
        const trans: UITransformComponent = this.ndParend.getComponent(UITransformComponent);
        // (总宽-减去空隙值 )/lv
        this.squureWh = (trans.contentSize.x - ((lv + 1) * this.ndLayoutComponent.spacingX)) / lv;
        this.ndLayoutComponent.cellSize = new Size(this.squureWh, this.squureWh);

        for (let i = 0; i < lv; i++) {
            for (let j = 0; j < lv; j++) {
                const prefab: Node = instantiate(this.itemBgPrefab);
                prefab.parent = this.ndParend;
                prefab.name = "squreBg" + i + "-" + j;
            }
        }
    }


    private copyArray()
        :
        [ItemPosition[]] {
        let newarray: [ItemPosition[]] = [[]];
        for (let i = 0; i < parseInt(this.userData.lv); i++) {
            newarray[i] = new Array(this.squareArray[i].length);
            for (let j = 0; j < parseInt(this.userData.lv); j++) {
                newarray[i][j] = new ItemPosition(v3(i, j, 0));
                if (this.squareArray[i][j].position.z != 0) {
                    newarray[i][j].position.z = this.squareArray[i][j].position.z;
                }
            }
        }
        return newarray;
    }


    private initSqure() {

        this.squareArray = [new Array<ItemPosition>(this.userData.array.length)];
        for (let i = 0; i < this.userData.array.length; i++) {
            this.squareArray[i] = new Array(this.userData.array[i].length);
            for (let j = 0; j < this.userData.array[i].length; j++) {

                this.squareArray[i][j] = new ItemPosition(v3(this.userData.array[i][j].x,
                    this.userData.array[i][j].y,
                    this.userData.array[i][j].z));
            }
        }
    }


    private generateRandom(score ?: number, row ?: number, column ?: number) {
        let randomNum = MathUtil.randomArray([2, 4]);
        if (score != null) {
            randomNum = score;
        }
        // 获取所有等于0的位置
        let nullArray: ItemPosition[] = [];
        for (const squareSingleArray of this.squareArray) {
            for (const square of squareSingleArray) {
                if (square.position.z === 0) {
                    nullArray.push(square);
                }
            }
        }
        let randomArray = MathUtil.randomArray(nullArray);
        if (row != null && column != null) {
            randomArray = this.squareArray[row][column];
        }
        randomArray.position.z = randomNum;
        this.addItem(randomArray, true);
    }


    private addItem(itemPosition
                        :
                        ItemPosition, isAction = false
    ) {
        let itemObj: Node = instantiate(this.itemPrefab);
        itemObj.parent = this.squereParent;
        itemObj.name = "item-" + itemPosition.position.z;
        let itemScript = itemObj.getComponent(Item);
        itemScript.init(itemPosition.position.z);
        itemObj.getComponent(UITransformComponent).contentSize = new Size(this.squureWh, this.squureWh);
        // 计算位置
        itemObj.position = this.transPosition(itemPosition.position);
        itemPosition.item = itemObj;
        if (isAction) {
            itemObj.scale = v3(0, 0, 0);
            tween(itemObj).to(0.15, {scale: v3(1, 1, 1)}, {easing: "sineInOut"}).start()
        }
    }


    private transPosition(vec3
                              :
                              Vec3
    ):
        Vec3 {
        let positionx: number = (vec3.y + 1) * this.ndLayoutComponent.spacingX
            + vec3.y * this.squureWh;

        let positionY: number = (vec3.x + 1) * this.ndLayoutComponent.spacingY
            + vec3.x * this.squureWh;
        return v3(positionx + (this.squureWh / 2), -positionY - (this.squureWh / 2), 0);
    }


    private async setScore(score
                               :
                               number
    ) {
        if (score > 0) {
            AudioMgr.inst.playOneShot(this.mergeMusic);
        }
        let transArray = this.transArray();
        console.log("历史局势", this.userData.arrayHistory)
        console.log("当前局势trans", transArray)

        this.userData.array = transArray;
        this.userData.arrayHistory.push(this.userData.array);

        this.userData.score = this.userData.score + score;


        this.userData = await post<GameUser>("/game/updateGameUser/" + this.userData.id, this.userData);
        if (this.userData.maxScore != null
            && this.userData.maxScore != 0) {
            console.log("更新最高分数", this.userData.maxScore)
            this.userInfo.game2048MaxScore = this.userData.maxScore;
            sys.localStorage.setItem('userInfo', JSON.stringify(this.userInfo));
        }
        this.updateView();
    }

    private transArray(): [Vec3DTO[]] {
        let vect3Array: [Vec3DTO[]] = [new Array<Vec3DTO>(this.squareArray.length)];
        for (let i = 0; i < this.squareArray.length; i++) {
            vect3Array[i] = new Array(this.squareArray[i].length);
            for (let j = 0; j < this.squareArray[i].length; j++) {

                vect3Array[i][j] = new Vec3DTO();
                vect3Array[i][j].x = this.squareArray[i][j].position.x
                vect3Array[i][j].y = this.squareArray[i][j].position.y
                vect3Array[i][j].z = this.squareArray[i][j].position.z
            }
        }
        return vect3Array;
    }


    private moveAnimation(itemObj
                              :
                              Tween<Node>, newPosition
                              :
                              Vec3, call ?: () => void
    ):
        Tween<Node> {
        let nodeTween = itemObj.to(0.08, {position: this.transPosition(newPosition)}, {easing: "linear"});
        if (call != null
        ) {
            nodeTween.call(call);
        }
        itemObj.start();
        return itemObj;
    }


    public clickHome() {
        director.loadScene("home");
    }

    /**
     * 打开游戏说明
     * @private
     */
    private openGameDesc() {
        Modal.Instance.show("2048游戏说明", `1.棋盘初始化随机出现两个数字，出现的数字仅可能为2或4。
2.玩家上下左右四个方向滑动,若有空格或可合并数字视为有效移动。
3.有效移动后会增加得分,并生成随机数字2或4。
4.棋盘被数字填满，无法进行有效移动，判负，游戏结束!
        `);
    }

    private testAi() {

        /*  try {
              setTimeout(()=>{
                  console.log("ai开始");
                  let grid: Grid = new Grid(4);
                  // 初始化完成
                  for (let i = 0; i < this.squareArray.length; i++) {
                      for (let j = 0; j < this.squareArray[i].length; j++) {
                          let square = this.squareArray[i][j];
                          if (square.position.z != 0) {
                              let tile = new Tile({
                                  x: square.position.x,
                                  y: square.position.y,
                              }, square.position.z);
                              grid.insertTile(tile)
                          }

                      }
                  }

                  let ai: AI = new AI(grid);
                  let best = ai.getBest();
                  console.log("移动", best);
              },3000)

          } catch (e) {
              console.error(e)
          }*/


    }

    private async showRank() {
        this.rankParent.destroyAllChildren();
        let res: WxUser[] = await get("/wx/getTop10");
        for (let i = 0; i < res.length; i++) {
            let wxUser = res[i];
            let node: Node = instantiate(this.rankPrefab);
            node.parent = this.rankParent;
            node.getChildByName("Title").getComponent(LabelComponent).string = "第" + (i + 1) + "名";
            if (i == 0) {
                node.getComponent(Palette).colorLB = Color.fromHEX(node.getComponent(Palette).colorLB, "#B8B8F7");
                node.getComponent(Palette).colorLT = Color.fromHEX(node.getComponent(Palette).colorLT, "#B8B8F7");
                node.getComponent(Palette).colorRB = Color.fromHEX(node.getComponent(Palette).colorRB, "#9400D3");
                node.getComponent(Palette).colorRT = Color.fromHEX(node.getComponent(Palette).colorRT, "#9400D3");
            } else if (i == 1) {
                node.getComponent(Palette).colorLB = Color.fromHEX(node.getComponent(Palette).colorLB, "#F1DFA6");
                node.getComponent(Palette).colorLT = Color.fromHEX(node.getComponent(Palette).colorLT, "#F1DFA6");
                node.getComponent(Palette).colorRB = Color.fromHEX(node.getComponent(Palette).colorRB, "#F1C020");
                node.getComponent(Palette).colorRT = Color.fromHEX(node.getComponent(Palette).colorRT, "#F1C020");
            } else if (i == 2) {
                node.getComponent(Palette).colorLB = Color.fromHEX(node.getComponent(Palette).colorLB, "#E2DCDC");
                node.getComponent(Palette).colorLT = Color.fromHEX(node.getComponent(Palette).colorLT, "#E2DCDC");
                node.getComponent(Palette).colorRB = Color.fromHEX(node.getComponent(Palette).colorRB, "#AFAAAA");
                node.getComponent(Palette).colorRT = Color.fromHEX(node.getComponent(Palette).colorRT, "#AFAAAA");
            }
            if (wxUser.wxUsername) {
                node.getChildByName("Label").getComponent(LabelComponent).string = wxUser.wxUsername + ":\n" + wxUser.game2048MaxScore + "分";
            } else {
                node.getChildByName("Label").getComponent(LabelComponent).string = "未授权" + ":\n" + wxUser.game2048MaxScore + "分";
            }
            if (wxUser.wxHead != null) {
                console.log('微信用户', wxUser.wxHead)
                assetManager.loadRemote<ImageAsset>(wxUser.wxHead, (err, imageAsset) => {
                    const spriteFrame = new SpriteFrame();
                    const texture = new Texture2D();
                    texture.image = imageAsset;
                    spriteFrame.texture = texture;
                    node.getChildByName("head").getComponent(SpriteComponent).spriteFrame = spriteFrame;
                });
            }
        }
    }
}

